package com.facerecognition

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import cn.wch.lib.ch34xMultiDriver
import cn.wch.lib.ch34xMultiManager
import com.faceidentify.FaceRecognitionActivity
import com.faceidentify.IdentifyRecognitionActivity
import com.faceidentify.IdentifyRegisterActivty
import com.faceidentify.R
import com.temHu.MyApp
import com.thermometry.ThermActivity
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

    private var isOpen = false
    private var handler: Handler? = null
    private var activity: MainActivity? = null
    lateinit var writeBuffer: ByteArray
    lateinit var readBuffer: ByteArray
    private val data: Byte = 0
    private var flow: Byte = 0
    private var parity: Byte = 0
    private val stop: Byte = 1
    var isConfiged = false
    private var tem: Double? = null
    private var thread: writeThread? = null
    private var hu: Double? = null
    private var manager: UsbManager? = null

    companion object {
        private val PERMISSIONS_STORAGE = arrayOf(
                android.Manifest.permission.READ_EXTERNAL_STORAGE,
                android.Manifest.permission.CAMERA,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
        private val REQUEST_EXTERNAL_STORAGE = 1
    }


    private var mContext: Context? = null
    private var relativelayoutThermometry: RelativeLayout? = null
    private var relativelayoutFaceRecognition: RelativeLayout? = null
    private var relativelayoutFaceRegister: RelativeLayout? = null
    private var relativelayoutFaceIdentify: RelativeLayout? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        ActivityCompat.requestPermissions(this@MainActivity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
        mContext = this
        //绑定组件方法
        initView()
        //事件监听方法
        initEvent()
        //初始化环境数据
        initEnv()


        handler = object : Handler() {
            @SuppressLint("HandlerLeak")
            override fun handleMessage(msg: Message) {
                when (msg.what) {
                    1 -> {
                        txt_thermometry.setText("")
                        //处理温度
                        tem = (getTem(msg.obj.toString())!!.toInt(16) / 10.0).toString().toDouble()
                        Log.d("TAG", tem.toString() + "摄氏度")
                        txt_thermometry.append(tem.toString() + "℃")
                        //处理湿度
                        txt_humidity.setText("")
                        hu = (getHu(msg.obj.toString())!!.toInt(16) / 10.0).toString().toDouble()
                        Log.d("TAG", hu.toString() + "%RH")
                        txt_humidity.append(hu.toString() + "%RH")
                    }
                }
            }
        }
    }

    private fun initEvent() {

        relativelayoutThermometry!!.setOnClickListener {
            isOpen = false;
            isConfiged = false;
            startActivity(Intent(mContext, ThermActivity::class.java))
        }

        relativelayoutFaceRecognition!!.setOnClickListener {
            startActivity(Intent(mContext, FaceRecognitionActivity::class.java))

        }
        relativelayoutFaceRegister!!.setOnClickListener {
            startActivity(Intent(mContext, IdentifyRegisterActivty::class.java))
        }
        relativelayoutFaceIdentify!!.setOnClickListener {
            startActivity(Intent(mContext, IdentifyRecognitionActivity::class.java))
        }

    }


    private fun initView() {
        //四大功能模块
        relativelayoutThermometry = findViewById<View>(R.id.relativelayout_thermometry) as RelativeLayout
        relativelayoutFaceRecognition = findViewById<View>(R.id.relativelayout_face_recognition) as RelativeLayout
        relativelayoutFaceRegister = findViewById<View>(R.id.relativelayout_face_register) as RelativeLayout
        relativelayoutFaceIdentify = findViewById<View>(R.id.relativelayout_face_identify) as RelativeLayout
    }

    //初始化环境数据
    fun initEnv() {
        manager = getSystemService(USB_SERVICE) as UsbManager
        MyApp.ch34xmag = ch34xMultiManager(applicationContext, manager)
        if (!UsbFeatureSupported()) // 是否支持USB HOST
        {
            val dialog: Dialog = AlertDialog.Builder(this@MainActivity)
                    .setTitle("提示")
                    .setMessage("设备不支持USB HOST")
                    .setPositiveButton("确定",
                            DialogInterface.OnClickListener { arg0, arg1 -> System.exit(0) }).create()
            dialog.setCanceledOnTouchOutside(false)
            dialog.show()
        }
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) // 保持常亮的屏幕的状态
        writeBuffer = ByteArray(512)
        readBuffer = ByteArray(512)
        isOpen = false
        activity = this
        open()
        if (isOpen) {
            config()
            Log.d("TAG", "开启读线程读取串口接收的数据")
            if (isConfiged) {
                Log.d("TAG", "设备配置成功")
                thread = writeThread()
                thread!!.start()
            }
        }
    }


    //打开设备
    fun open() {
        var mRet = 0
        if (!isOpen) {
            if (MyApp.ch34xmag == null) {
                MyApp.ch34xmag = ch34xMultiManager(applicationContext, manager)
            }
            Toast.makeText(this, "device Num:" + MyApp.ch34xmag!!.usbDeviceList.size, Toast.LENGTH_SHORT).show()
            if (MyApp.ch34xmag!!.usbDeviceList.size == 0) {
                Toast.makeText(this, "No device", Toast.LENGTH_SHORT).show()
                return
            }
            for (i in MyApp.ch34xmag!!.usbDeviceList.indices) {
                Log.d("permission", "Open" + MyApp.ch34xmag!!.usbDeviceList[i].deviceName)
                if (!MyApp.ch34xmag!!.OpenUsbDevice(MyApp.ch34xmag!!.usbDeviceList[i])) {
                    mRet++
                }
            }
            if (mRet != 0) {
                Toast.makeText(this, "打开失败，请授权或者重试", Toast.LENGTH_SHORT).show()
                MyApp.ch34xmag = null
                return
            }
            isOpen = true
            Log.d("permission", "readthread start")
            readthread().start()
        } else {
            isOpen = false //退出readthread
            MyApp.ch34xmag!!.CloseAll() //unregisterBroadcast
            MyApp.ch34xmag = null
        }
    }


    //配置设备
    fun config() {
        if (!isOpen) {
            Toast.makeText(this, "Not Open", Toast.LENGTH_SHORT).show()
            return
        }
        for (i in MyApp.ch34xmag!!.ch34xDriverList.indices) {
            isConfiged = if (MyApp.ch34xmag!!.ch34xDriverList[i].SetConfig(9600, data, stop, parity, flow)) {
                Toast.makeText(this, "Config Success", Toast.LENGTH_SHORT).show()
                true
            } else {
                Toast.makeText(this, "Config Fail", Toast.LENGTH_SHORT).show()
                false
            }
        }
    }

    inner  class readthread : Thread() {
        override fun run() {
            val buffer = ByteArray(4096)
            var recv: String
            while (true && isOpen) {
                //收发数据过程中移除设备，调用MyApp.ch34xmag.ch34xDriverList.remove(),用信号量防止同时访问
                try {
                    MyApp.ch34xmag!!.SemDriverList.acquire()
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
                var len = 0
                if(MyApp.ch34xmag!!.ch34xDriverList[0]!=null){
                    len = MyApp.ch34xmag!!.ch34xDriverList[0].ReadData(buffer, 4096)
                }
                if (len > 0) {
                    val msg: Message = Message.obtain()
                    recv = toHexString(buffer, len)!!
                    msg.obj = recv
                    msg.what = 1
                    handler!!.sendMessage(msg)
                }
                MyApp.ch34xmag!!.SemDriverList.release()
            }
            Log.d("MainActicity", "End readthread")
        }
    }

    //写数据
    inner class writeThread : Thread() {
        override fun run() {
            while (true) {
                Log.d("TAG", "writeThread")
                if (!isOpen) {
                    break
                }
                val To_Send: ByteArray = toByteArray("01 03 04 0A 00 02 E5 39")!!
                var ch34xdriver: ch34xMultiDriver
                Log.d("tag", "write" + MyApp.ch34xmag!!.ch34xDriverList.size)
                Log.d("tag", "write" + MyApp.ch34xmag!!.ch34xDriverList[1])
                ch34xdriver = MyApp.ch34xmag!!.ch34xDriverList[0]
                val retval = ch34xdriver.WriteData(To_Send, To_Send.size)
                Log.d("retval", retval.toString() + "")
                if (retval < 0) {
                    break
                }
                try {
                    sleep(3000)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }
        }
    }

    /**
     * 将String转化为byte[]数组
     *
     * @param arg 需要转换的String对象
     * @return 转换后的byte[]数组
     */
    private fun toByteArray(arg: String?): ByteArray? {
        if (arg != null) {
            /* 1.先去除String中的' '，然后将String转换为char数组 */
            val NewArray = CharArray(1000)
            val array = arg.toCharArray()
            var length = 0
            for (i in array.indices) {
                if (array[i] != ' ') {
                    NewArray[length] = array[i]
                    length++
                }
            }
            /* 将char数组中的值转成一个实际的十进制数组 */
            val EvenLength = if (length % 2 == 0) length else length + 1
            if (EvenLength != 0) {
                val data = IntArray(EvenLength)
                data[EvenLength - 1] = 0
                for (i in 0 until length) {
                    if (NewArray[i] >= '0' && NewArray[i] <= '9') {
                        data[i] = NewArray[i] - '0'
                    } else if (NewArray[i] >= 'a' && NewArray[i] <= 'f') {
                        data[i] = NewArray[i] - 'a' + 10
                    } else if (NewArray[i] >= 'A' && NewArray[i] <= 'F') {
                        data[i] = NewArray[i] - 'A' + 10
                    }
                }
                /* 将 每个char的值每两个组成一个16进制数据 */
                val byteArray = ByteArray(EvenLength / 2)
                for (i in 0 until EvenLength / 2) {
                    byteArray[i] = (data[i * 2] * 16 + data[i * 2 + 1]).toByte()
                }
                return byteArray
            }
        }
        return byteArrayOf()
    }


    /**
     * 将byte[]数组转化为String类型
     *
     * @param arg    需要转换的byte[]数组
     * @param length 需要转换的数组长度
     * @return 转换后的String队形
     */
     fun toHexString(arg: ByteArray?, length: Int): String? {
        var result = String()
        if (arg != null) {
            for (i in 0 until length) {
                result = (result
                        + (if (Integer.toHexString(
                                if (arg[i] < 0) arg[i] + 256 else arg[i].toInt()
                        ).length == 1
                ) "0"
                        + Integer.toHexString(
                        if (arg[i] < 0) arg[i] + 256 else arg[i].toInt()
                ) else Integer.toHexString(
                        if (arg[i] < 0) arg[i] + 256 else arg[i].toInt()
                )) + " ")
            }
            return result
        }
        return ""
    }

    //处理温度数据
    fun getTem(tem: String): String? {
        Log.d("Replace", tem.replace(" ", ""))
        val s = tem.replace(" ", "")
        return s.substring(6, 10)
    }

    //处理湿度数据
    fun getHu(Hu: String): String? {
        val h = Hu.replace(" ", "")
        val h1 = h.substring(10, 14)
        Log.d("Hu", h1 + "")
        return h1
    }


    fun UsbFeatureSupported(): Boolean {
        return packageManager.hasSystemFeature("android.hardware.usb.host")
    }

    override fun onDestroy() {
        super.onDestroy()
        isOpen = false
        isConfiged = false
        MyApp.ch34xmag!!.CloseAll()
    }

}



